package it.polimi.reTravelDream.beans;

import it.polimi.reTravelDream.dto.FlightDTO;
import it.polimi.reTravelDream.dto.HotelDTO;
import it.polimi.reTravelDream.dto.PrenotationDTO;
import it.polimi.reTravelDream.dto.TravelPackageDTO;
import it.polimi.reTravelDream.eao.FlightEAOLocal;
import it.polimi.reTravelDream.eao.PrenotationEAOLocal;
import it.polimi.reTravelDream.eao.TravelPackageActionEAOLocal;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.SessionScoped;
import javax.faces.bean.ViewScoped;

import org.primefaces.expression.impl.ThisExpressionResolver;



@ManagedBean(name="flights")
@SessionScoped

public class FlightsBean {
	
	
	@EJB
	private FlightEAOLocal flightAction;
	
	@EJB
	private TravelPackageActionEAOLocal travelPackageActionEAOLocal;
	
	@EJB
	private PrenotationEAOLocal prenotationEAOLocal;
	
	private List<FlightDTO> result;
	
	private boolean isEdit;
	
	private FlightDTO selectedFlight;
	private boolean isShowError;
	
	private String errorDeleteString;
	private String errorModification;
	
	private String flightModified="";
	private String errorDepartureCity="";
	private String erroreArrivalCity="";
	private String errorDate="";
	private String errorPrice="";
	
	public FlightsBean(){
		this.result=new ArrayList<FlightDTO>();
		this.selectedFlight=new FlightDTO();
		this.isEdit=false;
	}
	
	@PostConstruct
	public void getFLightList() {
		this.result=this.flightAction.getAllFlights();
		this.isShowError=false;

	}
	
	public List<FlightDTO> getResult() {
		return result;
	}
	
	public void editFlight(FlightDTO flightToEdit){	
		this.isShowError=false;		
		this.errorDeleteString="";
		this.errorModification="";
		
		this.selectedFlight=flightToEdit;
		
		this.isEdit=true;
		
	}
	
	
	
	public void saveFlightEdit(){
		
		this.flightModified="";
		this.errorDepartureCity="";
		this.erroreArrivalCity="";
		this.errorDate="";
		this.errorPrice="";
		
		 
		this.isShowError=false;
		boolean value=true;
		
		
		
		if (!this.checkIfPresentInAPAckage()) {
			System.out.println("checkIfPresentInAPAckage");
			this.errorModification="the flight "+this.selectedFlight.getId()+" is present in a package,"
					+ "if you want to modify it you must first remove it from"
					+ " the package and then you can modify it. If the item is present in a prenotation you can not "
					+ "modify it";
			value=false;
			this.isShowError=true;
		}
		
		
		if (!this.checkIfPresentInAPrenotation()) {

			this.errorModification="the flight "+this.selectedFlight.getId()+" is present in a prenotation,"
					+ "you cannot modify it";
			value=false;
			this.isShowError=true;
		}
		
		if (!value) {
			return;
		}
		
		if (!this.check()) {
			return;
		}
		
		
		
			FlightDTO mod=this.selectedFlight;
			this.flightAction.modifyFlight(mod);
			this.isEdit=false;
			this.result=this.flightAction.getAllFlights();
		
	}
	

	
	public void delete(FlightDTO flightToDelete){
		this.isShowError=false;
		this.errorDeleteString="";
		this.selectedFlight=flightToDelete;
		boolean value=true;
		
		if (!this.checkIfPresentInAPAckage()) {
			this.errorDeleteString="the flight "+flightToDelete.getId()+" is part of a package,"
					+ "if you want to delete it from the system you must first remove it from"
					+ " the package and then you can delete it from the system. Otherwise you can disable the item "
					+ "preventing it"
					+ "to be used again (you can re enabled it later if you want)";
			value=false;
			this.isShowError=true;
			
		}
		if (!this.checkIfPresentInAPrenotation()) {
			this.errorDeleteString="the flight "+flightToDelete.getId()+" is part of a prenotation,"
					+ "you cannot delete it from the system. You can disable the item "
					+ "preventing it"
					+ "to be used again (you can re enabled it later if you want)";
			value=false;
			this.isShowError=true;
		}
		if (!value) {
			return;
		}
		
		try {
			this.flightAction.removeFlight(flightToDelete);
			this.result=this.flightAction.getAllFlights();
		} catch (Exception e) {
			// TODO: handle exception
		}
		
	}
	
	private boolean check(){
		boolean value=true;
		
		if (!this.checkDepartureCity()) {
			this.errorDepartureCity="you must insert a city";
			value=false;
		}
		if (!this.checkArrivalCity()) {
			this.erroreArrivalCity="you must insert a city";
			value=false;

		}
		if(!this.checkDate()){
			this.errorDate="you must insert a date";
			value=false;
		}
		
		if(!this.checkPrice()){
			this.errorPrice="you must insert a valid price";
			value=false;
		}
		
		
		return value;
	}
	
	
	private boolean checkDepartureCity(){
		if(this.selectedFlight.getDepartureCity().isEmpty()){
			return false;
		}
		return true;
	}
	
	private boolean checkArrivalCity(){
		if(this.selectedFlight.getArrivalCity().isEmpty()){
			return false;
		}
		return true;
	}
	
	private boolean checkDate(){
		if(this.selectedFlight.getData()==null){
			return false;
		}
		return true;
	}
	private boolean checkPrice(){
		if (this.selectedFlight.getPrice()==0) {
			return false;
		}
		return true;
	}
	
	
	public void activate(FlightDTO flightToActivate){
		flightToActivate.setActive(true);
		try {
			this.flightAction.modifyFlight(flightToActivate);
			this.result=this.flightAction.getAllFlights();
		} catch (Exception e) {
			
		}
		
	}
	
	public void disable(FlightDTO flightToDisable){
		flightToDisable.setActive(false);
		try {
			this.flightAction.modifyFlight(flightToDisable);
			this.result=this.flightAction.getAllFlights();
		} catch (Exception e) {
			
		}
		
	}
	private boolean checkIfPresentInAPAckage(){
		List<TravelPackageDTO> allTravelPackageDTOs=this.travelPackageActionEAOLocal.getAllPackages();	
		
		for(TravelPackageDTO tDto:allTravelPackageDTOs){
			List<FlightDTO> flightInThePAckage=tDto.getPackageFlights();
						
			for(FlightDTO flightDTO:flightInThePAckage){				
					if (this.selectedFlight.getId()==flightDTO.getId()) {
						return false;					
					}
				}
		}
		return true;
	}
	
	private boolean checkIfPresentInAPrenotation(){
		List<PrenotationDTO> prenotationDTOs=this.prenotationEAOLocal.getAllPrenotation();
		for(PrenotationDTO prenotationDTO:prenotationDTOs){
			if (this.selectedFlight.getId()==prenotationDTO.getDepartureFlight().getId()) {
				return false;
			}
			if (this.selectedFlight.getId()==prenotationDTO.getReturnFlight().getId()) {

				return false;
			}
		}
		return true;
	}
	
	public void cancel(){
		this.isEdit=false;
		this.isShowError=false;
	}

	
	
	/**
	 * 
	 * getter and setter
	 */

	public void setResult(List<FlightDTO> result) {
		this.result = result;
	}

	public boolean isEdit() {
		return isEdit;
	}

	public void setEdit(boolean isEdit) {
		this.isEdit = isEdit;
	}

	public FlightDTO getSelectedFlight() {
		return selectedFlight;
	}

	public void setSelectedFlight(FlightDTO selectedFlight) {
		this.selectedFlight = selectedFlight;
	}

	public String getErrorDeleteString() {
		return errorDeleteString;
	}

	public void setErrorDeleteString(String errorDeleteString) {
		this.errorDeleteString = errorDeleteString;
	}

	public String getErrorModification() {
		return errorModification;
	}

	public void setErrorModification(String errorModification) {
		this.errorModification = errorModification;
	}

	public boolean isShowError() {
		return isShowError;
	}

	public void setShowError(boolean isShowError) {
		this.isShowError = isShowError;
	}

	public String getErrorDepartureCity() {
		return errorDepartureCity;
	}

	public void setErrorDepartureCity(String errorDepartureCity) {
		this.errorDepartureCity = errorDepartureCity;
	}

	public String getErroreArrivalCity() {
		return erroreArrivalCity;
	}

	public void setErroreArrivalCity(String erroreArrivalCity) {
		this.erroreArrivalCity = erroreArrivalCity;
	}

	public String getErrorDate() {
		return errorDate;
	}

	public void setErrorDate(String errorDate) {
		this.errorDate = errorDate;
	}

	public String getErrorPrice() {
		return errorPrice;
	}

	public void setErrorPrice(String errorPrice) {
		this.errorPrice = errorPrice;
	}

	public String getFlightModified() {
		return flightModified;
	}

	public void setFlightModified(String flightModified) {
		this.flightModified = flightModified;
	}
	
	
}
